package day09;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <a href="https://leetcode.cn/problems/roman-to-integer/">13. 罗马数字转整数</a>
 *
 * @author admin
 */
public class Answer {

    public static Map<String, Integer> nor = new HashMap<>();
    public static Map<String, Integer> spec = new HashMap<>();
    public AtomicInteger num = new AtomicInteger(0);

    static {
        spec.put("IV", 4);
        spec.put("IX", 9);
        spec.put("XL", 40);
        spec.put("XC", 90);
        spec.put("CD", 400);
        spec.put("CM", 900);
        nor.put("I", 1);
        nor.put("V", 5);
        nor.put("X", 10);
        nor.put("L", 50);
        nor.put("C", 100);
        nor.put("D", 500);
        nor.put("M", 1000);
    }

    public String specStrToInt(String str) {
        AtomicReference<String> newStr = new AtomicReference<>(str);
        if (str.length() > 0) {
            spec.keySet().forEach(key -> {
                if (str.contains(key)) {
                    Integer number = spec.get(key);
                    num.addAndGet(number);
                    String replace = newStr.get().replace(key, "");
                    newStr.set(replace);
                }
            });
        }
        return newStr.get();
    }

    public void norStrToInt(String str) {
        String[] strArr = str.split("");
        for (String s : strArr) {
            Integer number = nor.get(s);
            num.addAndGet(number);
        }
    }

    public int romanToInt1(String s) {
        HashMap<String, Integer> romanHash = new HashMap<String, Integer>();
        romanHash.put("I", 1);
        romanHash.put("V", 5);
        romanHash.put("X", 10);
        romanHash.put("L", 50);
        romanHash.put("C", 100);
        romanHash.put("D", 500);
        romanHash.put("M", 1000);
        romanHash.put("IV", 4);
        romanHash.put("IX", 9);
        romanHash.put("XL", 40);
        romanHash.put("XC", 90);
        romanHash.put("CD", 400);
        romanHash.put("CM", 900);

        int result = 0;
        for (int i = 0; i < s.length(); i++) {
            if (i < s.length() - 1) {
                String subStr = s.substring(i, i + 2);
                if (romanHash.containsKey(subStr)) {
                    result += romanHash.get(subStr);
                    i++;
                    continue;
                }
            }

            String subStr = s.substring(i, i + 1);
            result += romanHash.get(subStr);
        }

        return result;
    }

    /**
     * 最优解
     * @param s
     * @return
     */
    public int romanToInt2(String s) {
        int sum = 0;
        int preNum = getValue(s.charAt(0));
        for(int i = 1;i < s.length(); i ++) {
            int num = getValue(s.charAt(i));
            if(preNum < num) {
                sum -= preNum;
            } else {
                sum += preNum;
            }
            preNum = num;
        }
        sum += preNum;
        return sum;
    }

    private int getValue(char ch) {
        switch(ch) {
            case 'I': return 1;
            case 'V': return 5;
            case 'X': return 10;
            case 'L': return 50;
            case 'C': return 100;
            case 'D': return 500;
            case 'M': return 1000;
            default: return 0;
        }
    }

    public static void main(String[] args) {
        // 3999
        String max = "MMMCMXCIX";

        Answer answer = new Answer();
        // 1994
        String str = "LXXXIV";
        String s = answer.specStrToInt(str);
        System.out.println(answer.num.get());
        System.out.println(s);
        if (s.length() > 0) {
            answer.norStrToInt(s);
        }
        System.out.println(answer.num.get());
    }
}
